package com.xlh.controller.user;

import cn.hutool.core.util.RandomUtil;
import com.google.common.collect.Lists;
import com.xlh.common.Result;
import com.xlh.common.ResultEnum;
import com.xlh.constant.UserConstant;
import com.xlh.dto.course.CourseIndexDTO;
import com.xlh.dto.course.CourseIndexDataDTO;
import com.xlh.dto.system.ValueDTO;
import com.xlh.enums.SystemConfigEnum;
import com.xlh.pojo.system.ImageCode;
import com.xlh.pojo.system.SystemConfig;
import com.xlh.service.course.CourseService;
import com.xlh.service.system.SystemConfigService;
import com.xlh.util.RequestUtil;
import com.xlh.util.SmsUtil;
import com.xlh.util.VerifyCodeUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 未授权
 * <p>
 * Created by lx on 2019/1/25.
 */
@Api(tags = "UnauthorizedController", description = "未授权")
@RestController
@RequestMapping("/unauthorized")
public class UnauthorizedController {

    private static final Logger LOGGER = LoggerFactory.getLogger(UnauthorizedController.class);

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private CourseService courseService;

    @Value("${project.internet}")
    private Boolean recorded;

    @ApiOperation("是否需要获取验证码")
    @GetMapping("/image-code/show")
    public Result<Boolean> getImageCodeIsShow(HttpServletRequest request) {
        Integer sessionFailNum = (Integer) request.getSession().getAttribute(UserConstant.CODE_FAIL_NUM);
        return Result.success(sessionFailNum == null ? false : true);
    }

    @ApiOperation("获取logo等信息")
    @GetMapping("/config")
    public Result<Map<String, List<ValueDTO>>> getConfig(@RequestParam
                                                         @ApiParam(value = "key名集合", required = true)
                                                                 List<String> keys) {
        return Result.success(systemConfigService.listConfigByKey(keys));
    }

    @ApiOperation("获取图片验证码")
    @GetMapping("/image-code")
    public void getImageCode(HttpServletRequest request, HttpServletResponse response,
                             @RequestParam(required = false, defaultValue = "100") Integer width,
                             @RequestParam(required = false, defaultValue = "40") Integer height) {

        String code = VerifyCodeUtils.generateVerifyCode(4);
        try {
            VerifyCodeUtils.outputImage(width, height, code, response);
        } catch (IOException e) {

        }

        // 将验证码放置session中
        HttpSession session = request.getSession(true);
        session.removeAttribute(UserConstant.CODE_SESSION_KEY);
        session.setAttribute(UserConstant.CODE_SESSION_KEY, new ImageCode(code, UserConstant.CODE_EXPIRED_TIME));

    }

    @ApiOperation("发送短信验证码")
    @PostMapping("/sms-code/send")
    public Result sendSmsCode(HttpServletRequest request) {

        String code = RandomUtil.randomNumbers(6);

        HttpSession session = request.getSession(true);
        session.removeAttribute(UserConstant.SMS_CODE_SESSION_KEY);

        ImageCode sendSmsFail = (ImageCode) session.getAttribute(UserConstant.SMS_SEND_FAIL_SESSION_KEY);
        if (sendSmsFail != null && !sendSmsFail.isExpired()) {
            return Result.error(String.format(ResultEnum.SMS_CODE_SEND_FAIL_ERROR.getMessage(),
                    UserConstant.SMS_SEND_FAIL_EXPIRED_TIME / 60));
        } else {
            // 发送验证码
            try {
                SmsUtil.send((String) session.getAttribute(UserConstant.MOBILE_TEL_SESSION_KEY), code);
            } catch (Exception e) {
                session.removeAttribute(UserConstant.SMS_SEND_FAIL_SESSION_KEY);
                session.setAttribute(UserConstant.SMS_SEND_FAIL_SESSION_KEY,
                        new ImageCode("", UserConstant.SMS_SEND_FAIL_EXPIRED_TIME));
                throw e;
            }
        }

        session.setAttribute(
                UserConstant.SMS_CODE_SESSION_KEY, new ImageCode(code, UserConstant.SMS_CODE_EXPIRED_TIME));

        return Result.success();

    }

    @ApiOperation("获取首页信息")
    @GetMapping("/index")
    public Result<CourseIndexDTO> queryCourseIndex(
            @RequestParam(required = false, defaultValue = "8") @ApiParam(value = "课程分页数量") Integer coursePageSize,
            @RequestParam(required = false, defaultValue = "8") @ApiParam(value = "岗位分页数量") Integer skillPageSize,
            @RequestParam(required = false, defaultValue = "6") @ApiParam(value = "案例分页数量") Integer casePageSize,
            @RequestParam(required = false, defaultValue = "12")
            @ApiParam(value = "技能分页数量") Integer technologyPageSize) {
        return Result.success(
                courseService.getCourseIndex(coursePageSize, skillPageSize, casePageSize, technologyPageSize));
    }

    @ApiOperation("获取首页信息")
    @GetMapping("/index-course")
    public Result<CourseIndexDataDTO> queryCourseIndexInternet(
            @RequestParam(required = false, defaultValue = "8") @ApiParam(value = "课程分页数量") Integer coursePageSize,
            @RequestParam @ApiParam(value = "课程方向id", required = true) Long directionId) {
        return Result.success(courseService.getCourseDirectionIndex(coursePageSize, directionId));
    }

    @ApiOperation("获取申请码")
    @GetMapping("/invitation-code")
    public Result<String> getInvitationCode(HttpServletRequest request) {
        String ipAddress = RequestUtil.getIpAddress(request);
        Map<String, List<ValueDTO>> listMap = systemConfigService.listConfigByKey(Lists.newArrayList(
                SystemConfigEnum.INVITATION_CODE.getKey(), SystemConfigEnum.INVITATION_ACCESS_IP.getKey()));
        if (MapUtils.isEmpty(listMap)) {
            return Result.error(ResultEnum.NOT_FOUND);
        }
        List<ValueDTO> values = listMap.get(SystemConfigEnum.INVITATION_ACCESS_IP.getKey());
        if (CollectionUtils.isNotEmpty(values)
                && values.stream().filter(valueDTO -> Objects.equals(valueDTO.getKeyValue(), ipAddress)).count() == 0) {
            return Result.error(ResultEnum.FORBIDDEN);
        }
        return Result.success(listMap.get(SystemConfigEnum.INVITATION_CODE.getKey()).get(0).getKeyValue());
    }

    @ApiOperation("修改配置信息")
    @PutMapping("/config")
    @PreAuthorize("@permissionValidator.isAdmin()")
    public Result updateConfig(@RequestBody @Valid List<SystemConfig> configs) {
        configs.forEach(config -> {
            systemConfigService.updateSystemConfig(
                    SystemConfigEnum.getByKey(config.getKeyWord()), config.getKeyValue());
        });
        return Result.success();
    }

    @ApiOperation("是否是演示版本")
    @GetMapping("/internet")
    public Result<Boolean> isInternet() {
        return Result.success(recorded);
    }


}
